package com.aaa.sso.config;

import com.aaa.entity.LoginInfo;
import com.aaa.sso.fegin.LoginLogFegin;
import com.aaa.sso.fegin.UserFegin;
import com.aaa.sso.service.MyUserServer;
import com.aaa.utils.JwtUtil;
import com.alibaba.fastjson.JSON;
import com.aaa.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    private MyUserServer myUserServer;
    @Autowired
    private UserFegin userFegin;
    @Autowired
    private LoginLogFegin loginLogFeifn;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserServer).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .successHandler(successHandler())
                .failureHandler(failureHandler())
                .loginProcessingUrl("/login").permitAll();

        http.cors();
        http.csrf().disable();
        http.authorizeRequests().anyRequest().authenticated();
    }

    @Autowired
    private StringRedisTemplate redisTemplate;

    private AuthenticationSuccessHandler successHandler() {
        return (request, response, authentication) -> {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            //获取账号和权限
            User principal = (User) authentication.getPrincipal();
            String username = principal.getUsername();
            Collection<String> authorities = authentication.getAuthorities().stream().map(item->item.getAuthority()).collect(Collectors.toList());
            //根据账号和权限生产token;
            Map<String,Object> map=new HashMap<>();
            map.put("username",username);
            map.put("authorities",authorities);
            String token = JwtUtil.createJWT(map);
            //如何刷新过期时间--使用redis
            redisTemplate.opsForValue().set(token, JSON.toJSONString(map),30, TimeUnit.MINUTES);

            /**
             * 登录成功日志开始
             */
            com.aaa.entity.User user1 = userFegin.getByUsername(username);
            //获取当前用户的用户名
            String userName = user1.getUserName();
            //获取登录账户
            String login_account = user1.getPhone();
            //获取登录Ip登录地址
            String ip_addr = request.getRemoteAddr();
            //操作地点login_location
            String login_location = ip_addr.startsWith("192.168.") ? "内网IP" : "外网IP";
            //获取浏览器类型browser
            String agent = request.getHeader("user-agent");
            //判断字符串，Edge、Chrome、Safari、Firefox、IE浏览器或其它
            String browser="";
            if (agent.contains("Edge")) {
                browser="Edge";
            }
            else if (agent.contains("Chrome")) {
                browser="Chrome";
            }
            else if (agent.contains("Safari")) {
                browser="Safari";
            }
            else if (agent.contains("Firefox")) {
                browser="Firefox";
            }
            else {
                browser="IE或者其他";
            }
            //获取操作系统  写死不会
            String os="Windows 10";
                //登录状态
            String login_status="0";
                //登录类型
            String login_type="0";
            //提示信息
            String msg="登录成功";
            //登录时间login_time
            Date login_time = new Date();
            LoginInfo loginInfo = new LoginInfo(null,userName,login_account,ip_addr,login_location,browser,os,login_status,login_type,msg,login_time);
            loginLogFeifn.addLoginLog(loginInfo);
/**
 * 登录成功日志结束
 */
            //方便刷新token令牌的过期时间
            Result<String> result=new Result<>(2000,"登录成功",token);
            String jsonString = JSON.toJSONString(result);

            writer.print(jsonString);
            writer.flush();
            writer.close();
        };
    }
    //认证失败后处理的功能
    private AuthenticationFailureHandler failureHandler() {
        return (request, response, e) -> {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            Result<String> result=new Result<>(5000,"登录失败");
            String jsonString = JSON.toJSONString(result);
            writer.print(jsonString);
            writer.flush();
            writer.close();
        };
    }

}
